#include "odn_scene_CollisionManager.h"

namespace ouden
{
	namespace scene
	{
		
		//Allocates all scene objects into sectors for quick lookup
		bool ODN_CollisionManager::Sectorise()
		{
			
			//TODO: Clear sectors but leave static entities
			//Clear objects from sectors
			for (int x=0;x<sectorcount[0];x++) {
				for (int y=0;y<sectorcount[1];y++) {
					sectors[x][y].colliders.clear();
				}
			}
			
			//Loop through colliders 
			for (int i=0;i<colliders.size();i++) {
			
				//TODO: Need to check what kind of collider and allocate accordingly
				//Possibly make colliders allocate selves 
			
				//Calculate the sector that the current object is in 
				int px = int(colliders[i]->pos[0] / sectorsize[0]);
				int py = int(sceneobjects[i]->pos[1] / sectorsize[1]);
				
				//TODO: Check whether boundingbox is radial or total 
				//Calculate number of sectors the object spreads across
				Vector3D sector_spread = sceneobjects[i]->boundingbox / sectorsize;
				
				//TODO: Check this 
				//Loop across sector spread
				for (int x = int(px - sector_spread[0]);x < int(px + sector_spread[0]);x++) {
					for (int y = int(py - sector_spread[1]);y < int(py + sector_spread[1]);y++) {
						
						//Add the entity to the sector
						sectors[x][y].objects.push_back(sceneobjects[i]);
						
					}
				
				}
			}
			
		}
		
		bool ODN_CollisionManager::InteractColliders()
		{
			
			//Loop through colliders  
			for (int i=0;i<colliders.size();i++) {
				
				//Get nearby colliders from sectors 
				std::vector<ODN_Collider*> NearbyColliders = getNearbyColliders(colliders[i]);
				
				//Loop through the nearby colliders 
				for (int j=0;j<NearbyColliders.size();j++) {
					
					//Check that the nearby object still exists and that it is not the same object that we are checking with 
					if (NearbyColliders[j] && NearbyColliders[j] != colliders[i]) {
						
						//Raise the onColliderHit function of the parent object 
						colliders[i]->getParentObject()->onColliderHit(colliders[i], colliders[j]);
						
						//TODO: Response 
						
					}
					
				}
				
			}
			
		}
		
		//Collision detection routines 
		//----------------------------
		bool ODN_CollisionManager::checkCollide(ODN_CircleCollider* c1, ODN_CircleCollider* c2)
		{
			
			//If both have 0 radius then they can't collide 
			//TODO: Remove if not going to have many objects with 0 radius 
			if (c1->getRadius() * c2->getRadius == 0) return false;
			
			return false;
			
		}
		bool ODN_CollisionManager::checkCollide(ODN_LineCollider* l1, ODN_LineCollider* l2)
		{
			
			return false;
			
		}
		bool ODN_CollisionManager::checkCollide(ODN_CircleCollider* c, ODN_LineCollider* l)
		{
			
			return false;
			
		}
		//----------------------------
		
		std::vector<ODN_Collider*> ODN_CollisionManager::getNearbyColliders(ODN_PointCollider* Collider)
		{
			
			//Temporary object array 
			std::vector<ODN_Collider*> p;
			
			//Calculate the sector from the given position 
			int x = int(collider->point->pos[0] / sectorsize[0]);
			int y = int(collider->point->pos[1] / sectorsize[1]);
			
			//if (x >= 0 && x < sectorcount[0] && y >= 0 && y < sectorcount[1]) { 
				
				//Store the object array from the sector 
				p = sectors[x][y].colliders;
				
			//}
			
			//Return the object array 
			return p;
			
		}
		
	} //namespace scene 
} //namespace ouden 
